package encome.work.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import encome.work.dao.Orders;
import encome.work.dao.User;
import encome.work.dao.VolunteerInfo;
import encome.work.mapper.OrderMapper;
import encome.work.mapper.UserMapper;
import encome.work.mapper.VolunteerInfoMapper;
import encome.work.service.OrderService;
import encome.work.utils.RedisUtils;
import encome.work.utils.SecurityUtils;
import encome.work.utils.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @author fyftless
 */

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private VolunteerInfoMapper volunteerInfoMapper;

    @Resource
    private UserMapper userMapper;

    @Resource RedisUtils redisUtils;

    @Override
    public void add(Orders order) {
        orderMapper.insert(order);
    }

    @Override
    public void update(Orders order) {
        orderMapper.updateById(order);
    }

    @Override
    public void delete(Long id) {
        orderMapper.deleteById(id);
    }

    @Override
    public Page<Orders> findPage(Orders order, Integer page, Integer pageSize) {
        Page<Orders> pageInfo = new Page<>(page, pageSize);

        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getCategoryId, order.getCategoryId())
                .eq(Orders::getStatus, order.getStatus())
                .like(Orders::getContent, order.getContent());

        return orderMapper.selectPage(pageInfo, queryWrapper);
    }

    @Override
    public Orders findById(Long id) {
        return orderMapper.selectById(id);
    }

    @Override
    public Page<Orders> findPage(Integer page, Integer pageSize) {
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        return orderMapper.selectPage(pageInfo, queryWrapper);
    }

    @Override
    public void getOrder(Long id) {
        //获取接单发起人信息
        Long userId = SecurityUtils.getUser().getId();

        //判断订单是否可被抢，先从redis中获取，再去数据库取
        Orders order = (Orders) redisUtils.getValue("order_" + id);
        if(order == null){
            order = orderMapper.selectById(id);
            if(order == null)  //订单可能被用户删除
                throw new ServiceException("订单已被用户取消");
            redisUtils.setValueTime("order_" + id, order, 1000);
        }
        log.info("此刻的status为 ==> "+order.getStatus());
        if(order.getStatus() != 1) {
            throw new ServiceException("手慢了哦，订单已被他人抢先");
        }
        //尝试抢单
        order.setReceivedBy(userId);
        order.setStatus(2);

        LambdaUpdateWrapper<Orders> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Orders::getStatus, 1);

        int matchCount = orderMapper.update(order, lambdaUpdateWrapper);
        log.info("修改操作匹配数为 ==》 " + matchCount);

        if(matchCount > 0){
            //抢单成功，更新志愿者活动列表
            VolunteerInfo volunteerInfo = new VolunteerInfo();
            volunteerInfo.setUserId(userId);
            volunteerInfo.setOrderId(id);
            volunteerInfo.setCompleted(0);
            volunteerInfoMapper.insert(volunteerInfo);

            //更新缓存
            redisUtils.setValueTime("order_"+id, order, 1000);
        }else {
            throw new ServiceException("手慢了哦，订单已被他人抢先");
        }
    }

    @Override
    public void cancelOrderReceived(Long id) {

        //获取订单信息
        Orders order = getOrders(id);

        order.setReceivedBy(null);
        order.setStatus(1);

        orderMapper.updateById(order);
        redisUtils.setValueTime("order_"+id, order, 1000);

        //更新志愿者活动列表
        volunteerInfoMapper.deleteByOrderId(id);
    }

    @Override
    public void cancelOrder(Long id) {
        //获取接单发起人信息
        Long userId = SecurityUtils.getUser().getId();

        //获取订单信息
        Orders order = getOrders(id);

        //订单在未被接收的情况下可以取消
        if(order.getStatus() != 1){
            throw new ServiceException("订单已被接收，无法取消");
        }

        orderMapper.deleteById(id);
        redisUtils.delKey("order_" + id);
    }

    @Override
    public void finishOrder(Long id) {

        //获取订单信息
        Orders order = getOrders(id);

        order.setStatus(4);

        orderMapper.updateById(order);
        redisUtils.setValueTime("order_"+id, order, 1000);

        //更新志愿者活动列表
        LambdaQueryWrapper<VolunteerInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(VolunteerInfo::getOrderId, id);
        VolunteerInfo volunteerInfo = volunteerInfoMapper.selectOne(queryWrapper);
        volunteerInfo.setEndTime(LocalDateTime.now());
        volunteerInfo.setDate(LocalDateTime.now());
        volunteerInfo.setCompleted(1);
        volunteerInfoMapper.updateById(volunteerInfo);
        //增加志愿者的志愿活动次数
        userMapper.addVolunteerTimes(volunteerInfo.getUserId());
    }

    @Override
    public void getMedicine(Long id) {
        Orders order = getOrders(id);
        order.setStatus(3);
        orderMapper.updateById(order);
        redisUtils.setValueTime("order_"+id, order, 1000);
    }

    private Orders getOrders(Long id) {
        Orders order = (Orders) redisUtils.getValue("order_" + id);
        if(order == null){
            order = orderMapper.selectById(id);
            redisUtils.setValueTime("order_"+ id, order, 1000);
        }
        return order;
    }
}
